package com.corpgovernment.organization.service.impl;

import com.corpgovernment.api.organization.model.base.PageInfoResponse;
import com.corpgovernment.api.organization.model.post.*;
import com.corpgovernment.api.organization.model.post.front.PostEditRequest;
import com.corpgovernment.api.organization.model.user.employee.front.SubmitSelectEmpRequest;
import com.corpgovernment.api.organization.model.user.employee.front.SubmitSelectEmpVo;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.operatelog.constant.OperateLogContant;
import com.corpgovernment.common.utils.PageUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.entity.SyncOrganizationRequestEntity.SyncOrganizationInfoEntity.PostInfoEntity;
import com.corpgovernment.organization.entity.db.MbOrgEmployeeInfo;
import com.corpgovernment.organization.entity.db.MbOrgInfo;
import com.corpgovernment.organization.entity.db.MbPostInfo;
import com.corpgovernment.organization.entity.db.MbUserOrgRelation;
import com.corpgovernment.organization.mapper.MbPostMapper;
import com.corpgovernment.organization.operatelog.service.pojo.PostEditPojo;
import com.corpgovernment.organization.operatelog.service.pojo.PostInfoPojo;
import com.corpgovernment.organization.operatelog.service.pojo.PostPojo;
import com.corpgovernment.organization.service.IOrganizationInfoService;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.organization.service.IUserOrgRelationService;
import com.corpgovernment.organization.service.OrganizationBaseService;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.context.PageContext;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 岗位serviceImpl
 *
 * @author wangyujue
 */
@Service
@Slf4j
public class PostServiceImpl extends OrganizationBaseService implements IPostService {

    @Autowired
    private MbPostMapper mbPostMapper;

    @Autowired
    private IUserOrgRelationService userOrgRelationService;

    @Autowired
    private OrganizationEmployeeServiceImpl organizationEmployeeService;

    @Autowired
    private IOrganizationInfoService organizationInfoService;

    @Override
    public List<MbPostInfo> listByOrgId(String orgId) {
        MbOrgInfo mbOrgInfo = organizationInfoService.findRecentCompanyIdByOrgId(orgId);
        return getMbPostInfos(mbOrgInfo);
    }
    @Override
    public List<MbPostInfo> listByOrgId(String orgId, List<MbOrgInfo> allMbOrgInfoList) {
        MbOrgInfo mbOrgInfo = organizationInfoService.findRecentCompanyIdByOrgId(orgId,allMbOrgInfoList);
        return getMbPostInfos(mbOrgInfo);
    }

    private List<MbPostInfo> getMbPostInfos(MbOrgInfo mbOrgInfo) {
        if (mbOrgInfo == null){
            return Lists.newArrayList();
        }
        MbPostInfo mbPostInfo = new MbPostInfo();
        mbPostInfo.setOrgId(mbOrgInfo.getOrgId());
        mbPostInfo.setIsDeleted(false);
        return mbPostMapper.select(mbPostInfo);
    }

    @Override
    public MbPostInfo find(Long id) {
        MbPostInfo mbPostInfo = mbPostMapper.selectByPrimaryKey(id);
        return mbPostInfo;
    }

    @Override
    public Page list(Integer pageNum, Integer pageSize) {
        PageContext.startPage(pageNum, pageSize);
        List<MbPostInfo> list = mbPostMapper.selectAll();
        Page page = PageUtils.optPageBy(list, SearchPostPageResponse.class);
        return page;
    }

    @Override
    public int count() {
        int result = mbPostMapper.selectCount(new MbPostInfo());
        return result;
    }

    @Override
    public boolean save(MbPostInfo mbPostInfo) {
        int result = mbPostMapper.insertSelective(mbPostInfo);
//        insertOperateLog(mbPostInfo);
        return result > 0;
    }

    @Override
    public boolean update(MbPostInfo mbPostInfo) {
//        try {
//            MbPostInfo oldValue = postMapper.selectByPrimaryKey(mbPostInfo);
//            updateOperateLog(oldValue, mbPostInfo);
//        } catch (Exception e) {
//            log.error("更新操作获取oldValue失败，PostServiceImpl.updateEmployeeCard");
//        }
        int result = mbPostMapper.updateByPrimaryKeySelective(mbPostInfo);
        return result > 0;
    }


    @Override
    public boolean delete(Long id) {
        //删除职级
        int result = mbPostMapper.deleteById(id);
        deleteOperateLog(String.valueOf(id));
        return result > 0;
    }

    @Override
    public boolean deleteByOrgIdAndName(String orgId, List<String> positionNameList) {
       int result = mbPostMapper.deleteByOrgIdAndName(positionNameList, orgId);
       return result > 0;
    }

    @Override
    public List<MbPostInfo> findByName(String name) {
        return mbPostMapper.findByName(name);
    }

    @Override
    public List<MbPostInfo> findByNameAndOrgId(List<String> nameList, String orgId) {
        return mbPostMapper.findByNameList(nameList, orgId);
    }

    @Override
    public List<MbPostInfo> findByLikeName(List<String> orgIds, String name) {
        Example example = new Example(MbPostInfo.class);
        example.createCriteria().andEqualTo("isDeleted", false).andIn("orgId", orgIds);
        List<MbPostInfo> mbPostInfos = mbPostMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(mbPostInfos)) {
            return Lists.newArrayList();
        }
        return mbPostInfos.stream().filter(a -> a.getName().contains(name)).collect(Collectors.toList());
    }

    ;

    @Override
    public MbPostInfo findByNameAndOrgId(String name, String orgId) {
        if (StringUtils.isBlank(name) || StringUtils.isBlank(orgId)) {
            return null;
        }
        return mbPostMapper.findByNameAndOrgId(name, orgId);
    }

    @Override
    public MbPostInfo findByCodeAndOrgId(String code, String orgId) {
        if (StringUtils.isBlank(code) || StringUtils.isBlank(orgId)) {
            return null;
        }
        return mbPostMapper.findByCodeAndOrgId(code, orgId);
    }

    @Override
    public boolean deleteByOrgIds(List<String> orgIds) {
        int result = mbPostMapper.deleteByOrgIds(orgIds);
        deleteOperateLog(String.valueOf(orgIds));
        return result > 0;
    }

    @Override
    public boolean deletePostAndRelationById(Long postId) {
        MbPostInfo mbPostInfo = mbPostMapper.selectByPrimaryKey(postId);
        if (mbPostInfo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.POST_INFO_NOT_EXISTS);
        }
        //删除职级
        int result = mbPostMapper.deleteById(postId);
//        deleteOperateLog(mbPostInfo,new MbPostInfo());
        //清空职级人员关联表的postId字段
        userOrgRelationService.cleanPostIdByPostId(postId);
        return true;
    }

    @Override
    public MbPostInfo listPostByOrgIdAndUid(String orgId, String uId) {
        //查询到岗位id
        MbUserOrgRelation userOrgRelation = userOrgRelationService.find(orgId, uId);
        if (userOrgRelation == null) {
            return null;
        }
        return find(userOrgRelation.getPostId());
    }

    @Override
    public PostVo listPostByUidAndOrgId(String uId, String orgId) {
        if (StringUtils.isBlank(orgId) || StringUtils.isBlank(uId)) {
            return null;
        }
        MbPostInfo postInfo = listPostByOrgIdAndUid(orgId, uId);
        PostVo postVo = null;
        if (postInfo != null) {
            postVo = new PostVo();
            postVo.setId(postInfo.getId());
            postVo.setName(postInfo.getName());
            postVo.setOrgId(postInfo.getOrgId());
        }
        return postVo;
    }

    @Override
    public List<MbPostInfo> listByPostIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return mbPostMapper.selectByPostIds(ids);
    }

    @Override
    public boolean createPost(PostInfoEntity postInfo, String orgId) {
        if (postInfo == null || StringUtils.isBlank(orgId)) {
            return false;
        }
        String name = postInfo.getName();
        MbPostInfo old = mbPostMapper.findByNameAndOrgId(name, orgId);
        if (old != null) {
            return false;
        }
        MbPostInfo post = new MbPostInfo();
        post.setOrgId(orgId);
        post.setName(name);
        post.setIsDeleted(false);
        return mbPostMapper.insertSelective(post) > 0;
    }

    @Override
    public boolean createPost(String name, String orgId) {
        if (StringUtils.isBlank(name) || StringUtils.isBlank(orgId)) {
            return false;
        }
        MbPostInfo old = mbPostMapper.findByNameAndOrgId(name, orgId);
        if (old != null){
            return false;
        }
        MbPostInfo post = new MbPostInfo();
        post.setOrgId(orgId);
        post.setName(name);
        post.setIsDeleted(false);
        return mbPostMapper.insertSelective(post) > 0;
    }

    @Override
    public boolean createPostAndReturn(MbPostInfo resource) {
        if (StringUtils.isBlank(resource.getName()) || StringUtils.isBlank(resource.getOrgId())) {
            return false;
        }
        MbPostInfo old = mbPostMapper.findByNameAndOrgId(resource.getName(), resource.getOrgId());
        if (old != null){
            return false;
        }
        MbPostInfo post = new MbPostInfo();
        post.setOrgId(resource.getOrgId());
        post.setName(resource.getName());
        post.setCode(resource.getCode());
        post.setIsDeleted(false);
        return mbPostMapper.insertSelective(post) > 0;
    }

    @Override
    public List<PostVo> listPostByOrgId(String orgId) {
        List<PostVo> returnList = new ArrayList<>();
        // 查询岗位列表
        List<MbPostInfo> mbPostInfos = this.listByOrgId(orgId);
        for (MbPostInfo mbPostInfo : mbPostInfos) {
            PostVo postVo = new PostVo();
            postVo.setId(mbPostInfo.getId());
            postVo.setOrgId(mbPostInfo.getOrgId());
            postVo.setName(mbPostInfo.getName());
            returnList.add(postVo);
        }
        return returnList;
    }

    @Override
    public List<MbPostInfo> listByOrgIds(List<String> orgIds) {
        log.info("listByOrgIds:{}", JsonUtils.toJsonString(orgIds));
        Example example = new Example(MbPostInfo.class);
        example.createCriteria().andIn("orgId", orgIds).andEqualTo("isDeleted", Boolean.FALSE);
        return mbPostMapper.selectByExample(example);
    }

    @Override
    public int batchInsertPostInfo(List<MbPostInfo> mbPostInfoList) {
        if (CollectionUtils.isEmpty(mbPostInfoList)){
            return 0;
        }
        // 根据职级名称去重
        Map<String, MbPostInfo> map  = mbPostInfoList.stream().collect(Collectors.toMap(p->(p.getOrgId()+"_"+p.getName()), Function.identity(), (a,b)->a));
        log.info("batchInsertPostInfo: {}", JsonUtils.toJsonString(mbPostInfoList));
        return mbPostMapper.insertList(new ArrayList<>(map.values()));
    }

    @Override
    public ListPostByConditionResponse listPostByCondition(ListPostByConditionRequest request, BaseUserInfo baseUserInfo) {
        ListPostByConditionResponse response = new ListPostByConditionResponse();
        // 1.1 查询所有组织信息
        List<MbOrgInfo> orgInfoList = organizationInfoService.listAll();
        // 1.2 根据数据权限进行过滤
        orgInfoList = organizationInfoService.filterByRole(orgInfoList, baseUserInfo);
        if (CollectionUtils.isEmpty(orgInfoList)){
            return response;
        }
        List<String> orgIdList = orgInfoList.stream().map(MbOrgInfo::getOrgId).collect(Collectors.toList());
        // 2. 查询所有岗位
        List<MbPostInfo> postInfoList = this.listByOrgIds(orgIdList);
        if (CollectionUtils.isEmpty(postInfoList)){
            return response;
        }
        // 3. 过滤
        if (StringUtils.isNotBlank(request.getQuery())){
            List<MbPostInfo> postNameList = postInfoList.stream().filter(e -> StringUtils.isNotBlank(e.getName())).filter(e -> e.getName().contains(request.getQuery())).collect(Collectors.toList());
            List<MbPostInfo> postCodeList = postInfoList.stream().filter(e ->StringUtils.isNotBlank(e.getCode())).filter(e -> e.getCode().contains(request.getQuery())).collect(Collectors.toList());
            postNameList.addAll(postCodeList);
            postInfoList = postNameList.stream().distinct().collect(Collectors.toList());
        }
        // 4. 组装结果并返回
        List<ListPostByConditionVO> list = CollectionUtils.newArrayList();
        postInfoList.forEach(e ->{
            ListPostByConditionVO vo = new ListPostByConditionVO();
            vo.setPostId(e.getId().toString());
            vo.setPostName(e.getName());
            vo.setOrgId(e.getOrgId());
            vo.setPostCode(e.getCode());
            list.add(vo);
        });
        list.sort(Comparator.comparing(ListPostByConditionVO::getOrgId));
        // 5. 处理分页
        return pagePostList(request, response, list);
    }

    private ListPostByConditionResponse pagePostList(ListPostByConditionRequest request, ListPostByConditionResponse response, List<ListPostByConditionVO> list) {
        PageInfoResponse pageInfo = request.getPageInfo();
        // 无分页信息则全部返回
        if (Objects.isNull(pageInfo) || Objects.isNull(pageInfo.getPageNum()) || Objects.isNull(pageInfo.getPageSize())){
            response.setPostList(list);
            return response;
        }
        int pageSize = pageInfo.getPageSize();
        int pageNum = pageInfo.getPageNum();
        int count = list.size();
        int totalPage = (count + pageSize - 1) / pageSize;
        pageInfo.setCount(count);
        pageInfo.setTotalPage(totalPage);
        response.setPageInfo(pageInfo);
        // 超页返回空
        if (pageNum > totalPage){
            response.setPostList(CollectionUtils.newArrayList());
        } else {
            List<ListPostByConditionVO> subList = list.stream().skip((long) (pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            response.setPostList(subList);
        }
        return response;
    }

    /**
     * 转化数据
     *
     * @return
     */
    public PostEditPojo convertPojo(PostEditRequest postEditRequest) {
        PostEditPojo postEditPojo = new PostEditPojo();
        Integer status = postEditRequest.getStatus();

        Long id = postEditRequest.getId();
        // 状态（0：新增 1：编辑 2：删除）
        if (id != null) {
            MbPostInfo mbPostInfo = this.find(id);
            postEditPojo = JsonUtils.convert(mbPostInfo, PostEditPojo.class);
            postEditPojo.setStatus(status);
            return postEditPojo;
        }
        postEditPojo.setStatus(status);
        return postEditPojo;
    }


    /**
     * 转化数据
     *
     * @return
     */
    public PostPojo convertPojo(SubmitSelectEmpRequest submitSelectEmpRequest, Integer value) {
//        String id = submitSelectEmpRequest.getId();
        PostPojo postPojo = new PostPojo();
        postPojo.setType(submitSelectEmpRequest.getType());

        List<SubmitSelectEmpVo> employeeList = submitSelectEmpRequest.getData();

        if(OperateLogContant.BEFORE.equals(value)){
            List<SubmitSelectEmpVo> needDel = employeeList.stream()
                    .filter(p -> p.getIsNew() != null && !p.getIsNew())
                    .distinct()
                    .collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(needDel)){
                postPojo = this.get(needDel, postPojo);
                return postPojo;
            }
        }else {
            List<SubmitSelectEmpVo> needadd = employeeList.stream()
                    .filter(p -> p.getIsNew() != null && p.getIsNew())
                    .distinct()
                    .collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(needadd)){
                postPojo = this.get(needadd, postPojo);
                return postPojo;
            }


        }


//        // 查询岗位信息
//        MbPostInfo mbPostInfo = this.find(Long.valueOf(id));
//
//        // #1.查询岗位下人员列表
//        List<MbOrgEmployeeInfo>  list = organizationEmployeeService.listByPostId(Long.valueOf(id));
//        if (CollectionUtils.isEmpty(list)) {
//            return null;
//        }
//        List<String> orgIds = list.stream().map(MbOrgEmployeeInfo::getOrgId).distinct().collect(Collectors.toList());
//        // #2.查询组织结构名称
//        List<MbOrgInfo> mbOrgInfoList = organizationInfoService.listNameByOrgIds(orgIds);
//        if (CollectionUtils.isEmpty(mbOrgInfoList)) {
//            return null;
//        }
//        Map<String, String> orgNameMap = mbOrgInfoList.stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, MbOrgInfo::getName));
//        // 组装数据
//        PostInfoPojo postInfoPojo;
//        List<PostInfoPojo> infoPojoList = Lists.newArrayList();
//        for (MbOrgEmployeeInfo orgEmployeeVo : list) {
//            postInfoPojo = new PostInfoPojo();
//            postInfoPojo.setPhone(orgEmployeeVo.getMobilePhone());
//            postInfoPojo.setDepartment(orgNameMap.get(orgEmployeeVo.getOrgId()));
//            postInfoPojo.setName(orgEmployeeVo.getName());
//            postInfoPojo.setPostName(mbPostInfo.getName());
//            postInfoPojo.setUid(orgEmployeeVo.getUid());
//            if (mbPostInfo.getAllowance() != null) {
//                postInfoPojo.setAllowance(mbPostInfo.getAllowance().setScale(2, RoundingMode.HALF_UP).toString());
//            }
//            infoPojoList.add(postInfoPojo);
//        }
////        List<PostInfoPojo> newList = Lists.newArrayList();
//        if(CollectionUtils.isNotEmpty(infoPojoList)){
//            List<SubmitSelectEmpVo> data = employeeList;
//
//
//
//
//        }
//        if(CollectionUtils.isNotEmpty(infoPojoList)){
//            infoPojoList = infoPojoList.stream().distinct().collect(Collectors.toList());
//        }
//        postPojo.setList(infoPojoList);
        return null;
    }

    public PostPojo get(List<SubmitSelectEmpVo> selectEmpVoList, PostPojo postPojo) {
        MbUserOrgRelation mbUserOrgRelation;
        Map<String, String> orgNameMap;
        List<MbOrgInfo> mbOrgInfoList;
        MbPostInfo mbPostInfo;
        List<MbOrgEmployeeInfo> list;
        List<String> orgIds;
        Long postId = null;
        PostInfoPojo postInfoPojo;
        List<PostInfoPojo> infoPojoList = Lists.newArrayList();
        for (SubmitSelectEmpVo submitSelectVo : selectEmpVoList) {
            mbUserOrgRelation = userOrgRelationService.find(submitSelectVo.getOrgId(), submitSelectVo.getId());
            postId = mbUserOrgRelation.getPostId();
            // 查询岗位信息
            mbPostInfo = this.find(postId);
            if (mbPostInfo != null) {
                // #1.查询岗位下人员列表
                list = organizationEmployeeService.listByPostId(postId);
                orgIds = list.stream().map(MbOrgEmployeeInfo::getOrgId).distinct().collect(Collectors.toList());
                // #2.查询组织结构名称
                mbOrgInfoList = organizationInfoService.listNameByOrgIds(orgIds);
                if (CollectionUtils.isEmpty(mbOrgInfoList)) {
                    return postPojo;
                }
                orgNameMap = mbOrgInfoList.stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, MbOrgInfo::getName));
                if (!CollectionUtils.isEmpty(list)) {
                    for (MbOrgEmployeeInfo mbOrgEmployeeInfo : list) {
                        if (mbOrgEmployeeInfo.getUid().equals(submitSelectVo.getId())) {
                            postInfoPojo = new PostInfoPojo();
                            postInfoPojo.setPhone(mbOrgEmployeeInfo.getMobilePhone());
                            postInfoPojo.setDepartment(orgNameMap.get(mbOrgEmployeeInfo.getOrgId()));
                            postInfoPojo.setName(mbOrgEmployeeInfo.getName());
                            postInfoPojo.setPostName(mbPostInfo.getName());
                            postInfoPojo.setUid(mbOrgEmployeeInfo.getUid());
                            postInfoPojo.setIsNew(submitSelectVo.getIsNew());
                            if (mbPostInfo.getAllowance() != null) {
                                postInfoPojo.setAllowance(mbPostInfo.getAllowance().setScale(2, RoundingMode.HALF_UP).toString());
                            }
                            infoPojoList.add(postInfoPojo);
                        }
                    }
                }
            }
        }
        postPojo.setList(infoPojoList);
        return postPojo;
    }

}
